<template>
  <div>
    <v-card class="full-width-card">
      <v-card-title>角色管理</v-card-title>
      <v-card-text>
        <v-row class="mb-4" align="center" no-gutters>
          <v-col cols="12" sm="4" md="3">
            <v-text-field
              v-model="searchRoleName"
              label="角色名搜索"
              clearable
              density="comfortable"
              variant="outlined"
              hide-details
              @keyup.enter="onSearch"
            />
          </v-col>
          <v-col cols="12" sm="4" md="3">
            <v-select
              v-model="searchStatus"
              :items="statusOptions"
              label="状态"
              clearable
              density="comfortable"
              variant="outlined"
              hide-details
            />
          </v-col>
          <v-col cols="12" sm="4" md="5" class="d-flex justify-end align-center gap-btns">
            <v-btn
              variant="outlined"
              color="grey-darken-1"
              elevation="0"
              rounded
              @click="onSearch"
              size="large"
              class="mr-2"
              style="height: 40px; min-width: 90px; background: rgba(128,128,128,0.08);"
            >
              搜索
            </v-btn>
            <v-btn
              variant="outlined"
              color="grey-darken-1"
              elevation="0"
              rounded
              @click="onAddRole"
              size="large"
              style="height: 40px; min-width: 90px; background: rgba(128,128,128,0.08);"
            >
              新增
            </v-btn>
          </v-col>
        </v-row>
        <v-table>
          <thead>
            <tr>
              <th>角色ID</th>
              <th>角色名</th>
              <th>角色编码</th>
              <th>状态</th>
              <th>创建时间</th>
              <th>操作</th>
              <th>分配菜单</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="role in roles" :key="role.id">
              <td>{{ role.id }}</td>
              <td>{{ role.name }}</td>
              <td>{{ role.code }}</td>
              <td>{{ role.status === 1 ? '启用' : '停用' }}</td>
              <td>{{ role.create_time }}</td>
              <td>
                <v-btn size="small" variant="text" color="info" @click="onEditRole(role)">编辑</v-btn>
                <v-btn size="small" variant="text" color="error" @click="onDeleteRole(role)">删除</v-btn>
              </td>
              <td>
                <v-icon small class="cursor-pointer" color="primary" @click="openAssignMenuDialog(role)">mdi-format-list-bulleted</v-icon>
              </td>
            </tr>
          </tbody>
        </v-table>
        <div class="d-flex justify-space-between align-center mt-4">
          <span>本页共 {{ roles.length }} 条</span>
          <div class="d-flex align-center">
            <span style="margin-right: 12px;">第{{ page }}页 / 共{{ pageCount }}页</span>
            <v-pagination v-model="page" :length="pageCount" @input="onPageChange" />
          </div>
        </div>
      </v-card-text>
    </v-card>
    <v-dialog v-model="dialog" max-width="500px" persistent>
      <v-card>
        <v-card-title>{{ dialogMode === 'add' ? '新增角色' : '编辑角色' }}</v-card-title>
        <v-card-text>
          <v-form ref="formRef">
            <v-text-field v-model="dialogRole.name" label="角色名" required />
            <v-text-field v-model="dialogRole.code" label="角色编码" required />
            <v-select v-model="dialogRole.status" :items="statusOptions.filter(i => i.value !== null)" label="状态" required />
          </v-form>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn text @click="closeDialog">关闭</v-btn>
          <v-btn color="primary" @click="onSaveRole">保存</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
    <v-dialog v-model="assignMenuDialog" max-width="500px" persistent>
      <v-card>
        <v-card-title>分配菜单</v-card-title>
        <v-card-text>
          <v-select
            v-model="selectedMenuIds"
            :items="allMenus"
            item-title="menu_name"
            item-value="menu_id"
            label="选择菜单"
            multiple
            chips
            clearable
          />
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn text @click="closeAssignMenuDialog">关闭</v-btn>
          <v-btn color="primary" @click="onSaveAssignMenu">保存</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
    <v-dialog v-model="deleteDialog" max-width="400px">
      <v-card>
        <v-card-title>确认删除</v-card-title>
        <v-card-text>确定要删除该角色吗？此操作不可恢复。</v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn text @click="deleteDialog = false">取消</v-btn>
          <v-btn color="error" @click="confirmDeleteRole">删除</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import axios from 'axios'
import { API_BASE_URL } from '@/config/api'
import { saveOrUpdateRole, getMenuListByRoleId, allocateMenuToRole, getMenuTree, deleteRole } from '@/api/menu'

const roles = ref([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(20)
const searchRoleName = ref('')
const searchStatus = ref(null)
const statusOptions = [
  { title: '全部', value: null },
  { title: '启用', value: 1 },
  { title: '停用', value: 0 },
]

const pageCount = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))

const dialog = ref(false)
const dialogMode = ref('add') // 'add' or 'edit'
const dialogRole = ref({})
const formRef = ref(null)

const assignMenuDialog = ref(false)
const allMenus = ref([])
const selectedMenuIds = ref([])
let assignMenuRole = null

const deleteDialog = ref(false)
let deleteRoleId = null

function fetchData() {
  const formData = new URLSearchParams()
  formData.append('pageNum', page.value)
  formData.append('pageSize', pageSize.value)
  if (searchRoleName.value) formData.append('name', searchRoleName.value)
  if (searchStatus.value !== null && searchStatus.value !== undefined && searchStatus.value !== '') {
    formData.append('status', searchStatus.value)
  }
  axios.post(`${API_BASE_URL}/actions/role/list`, formData, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
  }).then(res => {
    roles.value = (res.data.list || [])
    total.value = res.data.total || 0
  })
}

function onPageChange(val) {
  page.value = val
  fetchData()
}

function onSearch() {
  page.value = 1
  fetchData()
}

function onAddRole() {
  dialogMode.value = 'add'
  dialogRole.value = { name: '', code: '', status: 1 }
  dialog.value = true
}

function onEditRole(role) {
  dialogMode.value = 'edit'
  dialogRole.value = { ...role }
  dialog.value = true
}

function onDeleteRole(role) {
  deleteRoleId = role.id
  deleteDialog.value = true
}

function closeDialog() {
  dialog.value = false
  setTimeout(() => { dialogRole.value = {} }, 300)
}

function onSaveRole() {
  // 新增不传id，编辑带id
  const roleDTO = {
    name: dialogRole.value.name,
    code: dialogRole.value.code,
    status: dialogRole.value.status
  }
  if (dialogMode.value === 'edit') {
    roleDTO.id = dialogRole.value.id
  }
  saveOrUpdateRole(roleDTO).then(() => {
    closeDialog()
    fetchData()
  })
}

function openAssignMenuDialog(role) {
  assignMenuRole = role
  assignMenuDialog.value = true
  // 获取所有菜单
  getMenuTree().then(res => {
    // 扁平化菜单树
    function flattenMenus(tree) {
      let arr = []
      for (const node of tree) {
        arr.push(node)
        if (node.children && node.children.length) {
          arr = arr.concat(flattenMenus(node.children))
        }
      }
      return arr
    }
    allMenus.value = flattenMenus(res.data.data || [])
    // 获取已分配菜单
    getMenuListByRoleId(role.id).then(r => {
      let menus = r.data.data || []
      selectedMenuIds.value = menus.map(m => m.menu_id)
    })
  })
}

function closeAssignMenuDialog() {
  assignMenuDialog.value = false
  assignMenuRole = null
  selectedMenuIds.value = []
}

function onSaveAssignMenu() {
  if (!assignMenuRole || !selectedMenuIds.value.length) return
  allocateMenuToRole({
    roleId: assignMenuRole.id,
    menuIds: selectedMenuIds.value.join(',')
  }).then(() => {
    closeAssignMenuDialog()
    // 可选：提示成功/刷新
  })
}

function confirmDeleteRole() {
  if (!deleteRoleId) return
  deleteRole(deleteRoleId).then(() => {
    deleteDialog.value = false
    deleteRoleId = null
    fetchData()
  })
}

onMounted(fetchData)
</script>

<style scoped>
.full-width-card {
  width: 100% !important;
  margin: 0 !important;
  box-sizing: border-box;
}
.v-card-text {
  padding: 0 !important;
}
.v-btn {
  min-width: 80px;
}
.gap-btns > .v-btn + .v-btn {
  margin-left: 12px;
}
</style> 